package com.traveldream.entity_managers;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import com.traveldream.entities.Booking;
import com.traveldream.entities.BookingPK;
import com.traveldream.entities.Invite;
import com.traveldream.entities.Packet;
import com.traveldream.entities.User;

/**
 * Session Bean implementation class InviteManagerBean
 */
@Stateless
public class InviteManagerBean implements InviteManager {

	// bisogna indicare che si usa la persistenza configurata nel package Common
	@PersistenceContext(unitName="TravelDreamCommon")
	EntityManager em;

	@Override
	public Invite create(Invite i) {
		// persist & flush em
		em.persist(i);
		em.flush();
		em.refresh(i);
	    // return persisted object
        return i;
	}

	@Override
	public List<Invite> findAll() {
		Query query = em.createNamedQuery("Invite.findAll",Invite.class);
    	List<Invite> results=new ArrayList<Invite>();
   		for( Object o : query.getResultList() ) 
   			results.add((Invite)o);
		return results;   
	}

	@Override
	public List<Invite> findBySender(User c) {
		Query query = em.createNamedQuery("Invite.findBySender",Booking.class).setParameter("senderEmail", c.getEmail());
    	List<Invite> results=new ArrayList<Invite>();
   		for( Object o : query.getResultList() ) 
   			results.add((Invite)o);
		return results;   
	}
	

	@Override
	public List<Invite> findByReceiver(User c) {
		Query query = em.createNamedQuery("Invite.findByReceiver",Booking.class).setParameter("receiverEmail", c.getEmail());
    	List<Invite> results=new ArrayList<Invite>();
   		for( Object o : query.getResultList() ) 
   			results.add((Invite)o);
		return results;   
	}

	@Override
	public boolean acceptInvite(Invite i, User receiver) {
		// pre-requisite: the receiver is already a user(customer)
		// invite accepted = delete invite for sender + add booking for reicever
		// this means that the sender cannot see his accepted invites but only 
		// the pending invites
		
		
		if(bookingCreation(receiver,i.getBooking().getPacket())) // 1. BOOKING CREATION
			return delete(i);	// 2. INVITE DELETION
		return false;
	}
	
	private boolean bookingCreation(User receiver,Packet p) {
		
		BookingPK key=new BookingPK();	
		key.setCustomerEmail(receiver.getEmail()); 
		key.setPacketId(p.getId());
		
		if(em.find(Booking.class, key)!=null)
			return false;

		Booking b=new Booking();
		b.setUser(receiver);
		b.setPacket(p);
		b.setId(key); 	
		b.setDate(new Date());		// day of today
		em.persist(b);
		em.flush();
		return true;
	}
	
	private boolean delete(Invite i) {
		Invite toDelete = em.merge(i);
		if( toDelete!=null ) {
			em.remove(toDelete);
			return true;
		}
		return false;
	}
}
